package com.ljw.gulimall.ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ljw.common.constant.WareConstant;
import com.ljw.common.to.SkuNameTo;
import com.ljw.common.utils.R;
import com.ljw.gulimall.ware.entity.PurchaseDetailEntity;
import com.ljw.gulimall.ware.entity.WareSkuEntity;
import com.ljw.gulimall.ware.feign.ProductFeignService;
import com.ljw.gulimall.ware.service.PurchaseDetailService;
import com.ljw.gulimall.ware.service.WareSkuService;
import com.ljw.gulimall.ware.vo.MergeVo;
import com.ljw.gulimall.ware.vo.PurchaseDoneVo;
import com.ljw.gulimall.ware.vo.PurchaseItemDoneVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljw.common.utils.PageUtils;
import com.ljw.common.utils.Query;

import com.ljw.gulimall.ware.dao.PurchaseDao;
import com.ljw.gulimall.ware.entity.PurchaseEntity;
import com.ljw.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;

    @Autowired
    private ProductFeignService productFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 查询新建的，未分配的采购单
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageUnReceivePurchase(Map<String, Object> params) {
        LambdaQueryWrapper<PurchaseEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PurchaseEntity::getStatus, "0").or().eq(PurchaseEntity::getStatus, "1");
        IPage<PurchaseEntity> page = new Query<PurchaseEntity>().getPage(params);
        baseMapper.selectPage(page, wrapper);
        return new PageUtils(page);
    }

    /**
     *合并采购单
     * @param mergeVo
     */
    @Override
    @Transactional
    public void mergePurchase(MergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();
        //如果没有分配采购单id，则新建一个采购单
        if (purchaseId == null){
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setStatus(WareConstant.PurchaseStatus.CREATED.getCode());
            baseMapper.insert(purchaseEntity);
            purchaseId = purchaseEntity.getId();
        }

        PurchaseEntity selectById = baseMapper.selectById(purchaseId);
        if (selectById.getStatus() == WareConstant.PurchaseStatus.CREATED.getCode() || selectById.getStatus() == WareConstant.PurchaseStatus.ASSIGNED.getCode()){
            //合并采购需求的id
            List<Long> items = mergeVo.getItems();

            //lambda表达式里面不允许使用已经修改的局部变量
            Long finalPurchaseId = purchaseId;

            //利用map修改订单需求中采购单id，同时修改订单需求中的状态码
            List<PurchaseDetailEntity> collect = items.stream().map(item -> {
                PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                purchaseDetailEntity.setId(item);
                purchaseDetailEntity.setPurchaseId(finalPurchaseId);
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatus.ASSIGNED.getCode());
                return purchaseDetailEntity;
            }).collect(Collectors.toList());

            //修改所有要修改的订单需求
            purchaseDetailService.updateBatchById(collect);
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setId(purchaseId);
            purchaseEntity.setUpdateTime(new Date());
            baseMapper.updateById(purchaseEntity);
        }
        else {
            return;
        }
    }

    /**
     * 采购员确定采购单
     * @param purchaseIds
     */
    @Override
    @Transactional
    public void received(List<Long> purchaseIds) {
        //1、查出要确定的采购单
        List<PurchaseEntity> purchaseEntities = baseMapper.selectBatchIds(purchaseIds);

        //2、只确定状态未新建、已分配的采购单，并修改采购单的状态为以确定
        List<PurchaseEntity> collect = purchaseEntities.stream().filter(purchaseEntity -> {
            return purchaseEntity.getStatus() == WareConstant.PurchaseStatus.CREATED.getCode() ||
                    purchaseEntity.getStatus() == WareConstant.PurchaseStatus.ASSIGNED.getCode();
        }).map( purchaseEntity -> {
            purchaseEntity.setStatus(WareConstant.PurchaseStatus.RECEIVE.getCode());
            purchaseEntity.setUpdateTime(new Date());
            return purchaseEntity;
        }).collect(Collectors.toList());

        //3、提交
        this.updateBatchById(collect);

        //4、修改采购单中每个采购需求的状态
        //4.1、查询出要修改的采购需求
        LambdaQueryWrapper<PurchaseDetailEntity> wrapper = new LambdaQueryWrapper<>();
//        collect.forEach( purchaseEntity -> {
//            wrapper.eq(PurchaseDetailEntity::getPurchaseId, purchaseEntity.getId()).or();
//        });
        wrapper.in(PurchaseDetailEntity::getPurchaseId, purchaseIds);
        purchaseDetailService.list(wrapper);
        //4.2、修改采购需求中的状态码为正在采购
        Collection<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.list(wrapper);
        List<PurchaseDetailEntity> updateDetails = purchaseDetailEntities.stream().map(purchaseDetailEntity -> {
            purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatus.BUYING.getCode());
            return purchaseDetailEntity;
        }).collect(Collectors.toList());
        //4.3、提交修改
        purchaseDetailService.updateBatchById(updateDetails);
    }

    @Override
    @Transactional
    public void done(PurchaseDoneVo purchaseDoneVo) {
        //1、改变采购单的状态
        Long purchaseId = purchaseDoneVo.getId();

        //2、改变采购项的状态
        Boolean flag = true;
        List<PurchaseItemDoneVo> items = purchaseDoneVo.getItems();
        List<PurchaseDetailEntity> updates = new ArrayList<>();
        List<Long> purchaseDetailIds = new ArrayList<>(); //采购成功的采购详情id
        for (PurchaseItemDoneVo item : items) {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            if (item.getStatus() == WareConstant.PurchaseDetailStatus.HAVEERROR.getCode()){
                flag = false;
                purchaseDetailEntity.setStatus(item.getStatus());
            }
            else {
                purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatus.FINISH.getCode());
                purchaseDetailIds.add(item.getItemId());
            }
            purchaseDetailEntity.setId(item.getItemId());
            updates.add(purchaseDetailEntity);
        }
        purchaseDetailService.updateBatchById(updates);

        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(purchaseId);
        purchaseEntity.setStatus(flag ? WareConstant.PurchaseStatus.FINISH.getCode() : WareConstant.PurchaseStatus.HAVEERROR.getCode());
        purchaseEntity.setUpdateTime(new Date());
        baseMapper.updateById(purchaseEntity);

        //3、将成功采购的进行入库
        //查出采购成功的采购详情
        List<PurchaseDetailEntity> purchaseDetailEntities = (List<PurchaseDetailEntity>) purchaseDetailService.listByIds(purchaseDetailIds);
        LambdaQueryWrapper<WareSkuEntity> wrapper = new LambdaQueryWrapper<>();
        //通过采购成功的采购详情查处构建出查询其对应的库存
        for (PurchaseDetailEntity purchaseDetailEntity : purchaseDetailEntities) {
            wrapper.or( w -> {
                w.eq(WareSkuEntity::getSkuId, purchaseDetailEntity.getSkuId());
                w.eq(WareSkuEntity::getWareId, purchaseDetailEntity.getWareId());
            });
        }
        //要更新的库存（库存表中可能不存在采购成功的对应的sku）
        List<WareSkuEntity> wareSkuEntities = wareSkuService.list(wrapper);
        for (WareSkuEntity skuEntity : wareSkuEntities) {
            for (PurchaseDetailEntity purchaseDetailEntity : purchaseDetailEntities) {
                if (skuEntity.getSkuId().equals(purchaseDetailEntity.getSkuId()) &&
                        skuEntity.getWareId().equals(purchaseDetailEntity.getWareId())) {
                    Integer originStock = skuEntity.getStock();
                    Integer increaseStock = purchaseDetailEntity.getSkuNum();
                    skuEntity.setStock(originStock + increaseStock);
                    break;
                }
            }
        }
        wareSkuService.updateBatchById(wareSkuEntities);

        //库存表中可能不存在采购成功的对应的sku，则需要插入sku的库存信息
        List<WareSkuEntity> insertWareSkus = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();

        //排除已经存在的库存信息
        for (PurchaseDetailEntity purchaseDetailEntity : purchaseDetailEntities) {
            for (WareSkuEntity skuEntity : wareSkuEntities) {
                if (!(purchaseDetailEntity.getSkuId().equals(skuEntity.getSkuId()) &&
                        purchaseDetailEntity.getWareId().equals(skuEntity.getWareId()))) {
                    WareSkuEntity wareSkuEntity = new WareSkuEntity();
                    wareSkuEntity.setSkuId(purchaseDetailEntity.getSkuId());
                    wareSkuEntity.setWareId(purchaseDetailEntity.getWareId());
                    wareSkuEntity.setStock(purchaseDetailEntity.getSkuNum());
                    skuIds.add(purchaseDetailEntity.getSkuId());
                    insertWareSkus.add(wareSkuEntity);
                    break;
                }
            }
        }

        if (skuIds.size() > 0){
            //查找对应sku的名称
            R result = productFeignService.getSkusByIds(skuIds);
            List<SkuNameTo> skuNameTos = (List<SkuNameTo>) result.get("skuNameTos");

            //设置库存字段中sku的名称
            for (WareSkuEntity wareSkus : insertWareSkus) {
                for (SkuNameTo skuNameTo : skuNameTos) {
                    if (wareSkus.getSkuId().equals(skuNameTo.getSkuId())) {
                        wareSkus.setSkuName(skuNameTo.getSkuName());
                        break;
                    }
                }
            }

            //保存
            wareSkuService.saveBatch(insertWareSkus);
        }

    }





}